/*
 * For legal stuff see the file COPYRIGHT
 */
#import <sys/time.h>
#import <stdio.h>
#import <stdlib.h>
#import "Session.h"
#import "Preferences.h"

extern void freeAndCopy( char **ptr, const char *str );
extern char *NXCopyStringBuffer(const char *buffer);

@implementation Session

static ColDesc LayoutOne[] = {
  { 3.0,	"startDateString",	(SEL)0 },
  { 60.0,	"startTimeString",	(SEL)0 },
  { 100.0,	"durationString",	(SEL)0 },
  { 134.0,	"description",		(SEL)0 },
  { 0.0,	NULL,			(SEL)0 },
};

/*
 * If the user selected the "ShowEndTimes" preference,
 * the spacing gets wider to accomodate the additional info.
 */
static ColDesc LayoutTwo[] = {
  { 3.0,	"startDateString",	(SEL)0 },
  { 60.0,	"sessionBounds",	(SEL)0 },
  { 134.0,	"durationString",	(SEL)0 },
  { 170.0,	"description",		(SEL)0 },
  { 0.0,	NULL,			(SEL)0 },
};

+ initialize
{
  ColDesc *ptr;

  /* Initialize the selectors in the ColDesc table */ 
  for ( ptr = LayoutOne; ptr->method; ptr++ )
    ptr->selector = sel_getUid( ptr->method );

  for ( ptr = LayoutTwo; ptr->method; ptr++ )
    ptr->selector = sel_getUid( ptr->method );

  return self;
}

- init:(const char *)startDate
       time:(const char *)startTime
       duration:(int)elapsedMinutes
       description:(const char *)desc
{
  [self setStartDateString:startDate];
  [self setStartTimeString:startTime];
  [self setDescription:desc];
  minutes = elapsedMinutes;
  return self;
}

- (void) freeDesc
{
  if ( description ) {
    free( description );
    description = NULL;
  }
}

- free
{
  [self freeDesc];
  return [super free];
}

- (ColDesc *)colDesc
{
  return [[Preferences new] showEndTimes] ? LayoutTwo : LayoutOne;
}

- setMinutes:(int)value
{
  minutes = value;
  return self;
}

/* Must we parse the string and convert to UNIX format? Why bother? */
- setStartDateString:(const char *)str
{
  freeAndCopy( &startDateString, str );
  return self;
}

- setStartTimeString:(const char *)str
{
  freeAndCopy( &startTimeString, str );
  return self;
}

- setDescription:(const char *)desc
{
  [self freeDesc];
  description = NXCopyStringBuffer(desc);
  return self;
}

- (const char *)startTimeString
{
  return startTimeString;
}

- (const char *)sessionBounds
{
  static char buf[80];
  int startHr, startMin, endHr, endMin;

  sscanf( startTimeString, "%d:%d", &startHr, &startMin );
  endHr  = startHr  + minutes / 60;
  endMin = startMin + minutes % 60;

  if ( endMin > 59 )
    endHr++;
  
  endMin %= 60;
  endHr  %= 24;

  sprintf( buf, "%02d:%02d-%02d:%02d", startHr, startMin, endHr, endMin );
  return buf;
}

- (const char *)startDateString
{
  return startDateString;
}

- (const char *)description
{
  return description;
}

- (int)minutes
{
  return minutes;
}

- (float)hours
{
  return minutes/60.0;
}

- (const char *)durationString
{
  static char buf[20];

  sprintf( buf, "%d:%02d", minutes / 60, minutes % 60 );
  return buf;
}

/*
 * For use in comparisons, convert date such as 11/21/93 to a
 * single integer 932111. THIS SHOULD BE CACHED! (TBD)
 */
- (int)dateValue
{
  int day, month, year;

  sscanf( startDateString, "%d/%d/%d", &month, &day, &year );
  return ( year * 10000 + month * 100 + day );
}

/*
 * Similarly, convert 12:45 to the integer 1245.
 */
- (int)timeValue
{
  int minute, hour;

  sscanf( startTimeString, "%d:%d", &hour, &minute );
  return ( hour * 100 + minute );
}

- read:(NXTypedStream *) stream
{
  NXReadTypes( stream, "***i", &description, &startTimeString,
	      &startDateString, &minutes );
  return self;
}

- write:(NXTypedStream *) stream
{
  NXWriteTypes( stream, "***i", &description, &startTimeString,
	       &startDateString, &minutes );
  return self;
}

@end
